﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using System.Web.UI;

// The request context is the heart of BigfootMVC. It acts as the interface for all operations
// against the database, dnn, request and response objects, posted data, etc. 
// The reason for this isolation is to facilitate unit testing. By decoupling the code from the 
// dependencies of the intristic asp.net objects, we are able to fake up a request context object
// and be confident that all the code within the system will work using our fake context.
namespace Mitmar.Web.Mvc.DNN
{

    public class RequestContext
    {

        private IContextCache ContextCache { get; set; }

        public RequestContext()
        {
            ContextCache = new ASPContextCache();
            Request = new ASPRequest();
            Response = new ASPResponse();
            Server = new ASPServer();

            Route = new RouteInfo
                         {
                             Controller = Request.QueryString[Params.Controller] ?? "Home",
                             Action = Request.QueryString[Params.Action] ?? "Default"
                         };

            // DNN cache is application wide
            if (App.Cache.Contains(Params.Cache.DNNHelper) == false)
            {
                App.Cache.Add(Params.Cache.DNNHelper, new DNNHelper());
            }
            DNN = (IDNNHelper)App.Cache.GetValue(Params.Cache.DNNHelper);

            // DB cache is application wide
            if (App.Cache.Contains(Params.Cache.DB) == false)
            {
                App.Cache.Add(Params.Cache.DB, new DataProvider());
            }
            DB = (DataProvider)App.Cache.GetValue(Params.Cache.DB);
        }

        public RequestContext(IContextCache contextCache, IRequest request, IResponse response, RouteInfo route, IServer server, IDNNHelper dnnprovider, DataProvider db)
        {
            ContextCache = contextCache;
            Request = request;
            Response = response;
            Route = route;
            Server = server;
            DNN = dnnprovider;
            DB = db;
        }

        public object this[string key]
        {
            get
            {
                return ContextCache.Items.ContainsKey(key) ? ContextCache[key] : null;
            }
            set
            {
                if (ContextCache.Items.ContainsKey(key))
                {
                    ContextCache[key] = value;
                }
                else
                {
                    ContextCache.Items.Add(key, value);
                }
            }
        }

        public IRequest Request { get; set; }

        public IResponse Response { get; set; }

        public IServer Server { get; set; }

        public string ApplicationPath { get { return Request.ApplicationPath; } }

        public string RequestType { get { return Request.RequestType; } }

        public bool IsAuthenticated { get { return Request.IsAuthenticated; } }

        public string UserName { get { return Request.UserName; } }

        public NameValueCollection Headers { get { return Request.Headers; } }

        public string MapPath(string virtualPath) { return Server.MapPath(virtualPath); }

        public string ExecutePage(Page currentPage)
        {
            // Render the page
            var output = new StringWriter();
            Server.Execute(currentPage, output, true);

            // Return the rendered output
            return output.ToString();
        }

        public RouteInfo Route { get; set; }

        public IDNNHelper DNN { get; set; }

        public DataProvider DB { get; set; }

        // Gets the value of the item weather it is in the querystring or posted form
        public string RequestValue(string key)
        {
            if (Request.QueryString[key] != null)
                return Request.QueryString[key];

            return Request.Form[key] ?? string.Empty;
        }

        // A name value collection including QueryString and Form values
        public NameValueCollection RequestValues { get { return new NameValueCollection { Request.QueryString, Request.Form }; } }

        public NameValueCollection QueryString { get { return Request.QueryString; } }

        public NameValueCollection Form { get { return Request.Form; } }

        public HttpCookieCollection Cookies { get { return Request.Cookies; } }

        public List<HttpPostedFile> Files { get { return Request.Files; } }

    }


}

